home *** CD-ROM | disk | FTP | other *** search
- //
- // Copyright (C) 1991 Texas Instruments Incorporated.
- //
- // Permission is granted to any individual or institution to use, copy, modify,
- // and distribute this software, provided that this complete copyright and
- // permission notice is maintained, intact, in all copies and supporting
- // documentation.
- //
- // Texas Instruments Incorporated provides this software "as is" without
- // express or implied warranty.
- //
- // Created: MBN 05/16/89 -- Initial design and implementation
- // Updated: MBN 06/01/89 -- Implemented the notion of current position.
- // Updated: MBN 06/06/89 -- Separated and derived Hash_Table from Base_Hash
- // to reduce replication of common code.
- // Updated: LGO 06/20/89 -- Use correct default hash and compare for char* keys
- // Updated: LGO 07/03/89 -- Fix resize bug in the put method
- // Updated: MBN 08/19/89 -- Changed template usage
- // Updated: MBN 09/20/89 -- Added conditional exception handling
- // Updated: MBN 09/26/89 -- Added method to return key at current position
- // Updated: LGO 10/02/89 -- Substituted Tkey and Tval for T1 and T2
- // Updated: MBN 10/07/89 -- Changed get() method to match Association + Symbol
- // Updated: MBN 10/11/89 -- Fixed operator==() for tables with different bucket
- // count but same elements -- tables grew separately
- // Updated: MBN 10/12/89 -- Changed "current_position" to "curpos", added
- // current_position() method for Iterator<Type>, and
- // converted state from bit set to bit set/get macros
- // Updated: LGO 10/16/89 -- Re-write operator<< to be const
- // Updated: MBN 10/19/89 -- Made compare_keys and compare_values_s slots static
- // and added optional argument to set_compare methods
- // Updated: MBN 12/15/89 -- Fixed no-dereferenced pointer-to-function in find()
- // Updated: LGO 02/07/90 -- Change resize to not use a tempoorary for key and
- // value. Avoids extra constructor and destructor
- // calls.
- // Updated: MBN 02/23/90 -- Changed size arguments from long to unsigned long
- // Updated: MJF 06/30/90 -- Added base class name to constructor initializer
- // Updated: VDN 02/21/92 -- New lite version
- //
- // The Hash_Table<Tkey,Tval> class is publicly derived from the Hash_Table
- // class and implements hash tables of user-specified types for both the key
- // and the value. This is accompilshed by using the parameterized type
- // capability of C++. The Hash Table class is dynamic in nature. It's size
- // (ie. the number of buckets in the table) is always some prime number. Each
- // bucket holds 8 items. No wholes are left in a bucket; if a key/value pair
- // is removed from the middle of a bucket, following entries are moved up.
- // When a hash on a key ends up in a bucket that is full, the table is
- // enlarged. The Hash_Table<Tkey,Tval> class is parameterized over two types.
- // The first type Tkey specifies the type of the key, and the second type Tval
- // specifies the type of the value.
- //
- // The private data section of a Hash Table has a slot that points to the
- // physical memory allocated for some prime number of buckets each of which has
- // memory allocated for 8 items. The number of buckets currently in the table
- // is accessed by an index into a global table of selected prime numbers. This
- // global table eliminates the somewhat expensive runtime computation of prime
- // numbers. The table consists of prime numbers where the difference between
- // any two successive entries gets progressively larger as you move through the
- // table. The specified range of primes results in an arbitrary limitation of
- // 2^22 entries in a single hash table.
- //
- // When a hash on a key ends up in a bucket that is full, the table is enlarged
- // to the next prime number of buckets or to the prime number that is at least
- // large enough to accommodate a user-specified growth ratio. The entries in
- // the buckets are then rehashed into the new table. Selection of an
- // appropriate hash function is crucial to uniform distribution through the
- // table. The result of the hash function is then divided by the prime number
- // of buckets to accomplish this. A user-supplied function should do something
- // similar.
- //
- // Other items in the private data section (inherited from Base Hash) include a
- // pointer to a byte vector (that is, unsigned char) that maintains a count of
- // the number of entries in each bucket, a growth ratio that can be used to set
- // a growth rate percentage when necessary, an entry count, an index into the
- // prime number table that indicates the number of buckets in the table, and a
- // current position that maintains the bucket number and index into the bucket
- // of the last hash operation.
- //
- // Three other slots contain a pointer to a key compare function, a pointer to
- // a value compare function, and a pointer to a hash function, respectively.
- // The compare functions are used in equality operations on key/value items.
- // The default compare function is the built-in == operator. The default hash
- // function is either a simple 32 bit value if sizeof(Tkey) is 4, that is
- // shifted left three bits with the result modulo the number of buckets
- // determining the hash. This is ideal when Tkey is a pointer to a key. If
- // sizeof(Tkey) is greater than 4, then the 32 bit value used is the result of
- // exclusive-oring successive 32-bit values for the length of Tkey, and then
- // applying the same bit shift and modulo operation as before.
- //
- // Three different constructors are provided. The first constructor takes no
- // arguments and creates a hash table with three buckets that can contain a
- // total of 24 items. The second constructor accepts an integer argument and
- // creates a hash table of some prime number of buckets that can accomodate at
- // least the specified number of items. Finally, the third constructor takes a
- // single argument consisting of a reference to a Hash Table and duplicates its
- // size and contents.
- //
- // The Hash Table class implements the notion of a current position. This is
- // useful for iterating through the table of hashed values. The current
- // position is maintained in a a long that is accessed via several preprocessor
- // macros to select bits. The first bit field is of length 24 and maintains the
- // bucket (prime) number last used. The second bit field is of length 8 and
- // maintains the index of the last item in a bucket. Methods to reset, move to
- // the next and previous, find, and get the value at the current position are
- // provided.
- //
- // Methods are provided to put a value based on some key into the table, get a
- // value based on some key from the table, remove a value based on some key
- // from the table, and to clear all values from the table entirely. The output,
- // assignment, and equality operators are overloaded for hash tables. Finally,
- // two functions to set the hash and compare functions for an instance of a
- // hash table, accessor methods to get the bucket and total entry count, and a
- // method to set the growth ratio are also available.
-
- #ifndef HASH_TABLEH // If no Hash Table class,
- #define HASH_TABLEH // define it
-
- #ifndef BASE_HASH_TABLEH // If no Base Hash class,
- #include <cool/Base_Hash.h> // define it
- #endif
-
- template <class Tkey, class Tval> CoolHash_Table {
- struct CoolHash_Table<Tkey,Tval>_pair { // Structure for hash/value
- Tkey key;
- Tval value;
- };
-
- struct CoolHash_Table<Tkey,Tval>_bucket { // Structure for bucket
- struct CoolHash_Table<Tkey,Tval>_pair data[BUCKET_SIZE];
- };
-
- typedef Boolean
- (*CoolHash_Table<Tkey,Tval>_Key_Compare) (const Tkey&, const Tkey&);
- typedef Boolean
- (*CoolHash_Table<Tkey,Tval>_Value_Compare) (const Tval&, const Tval&);
- typedef unsigned long (*CoolHash_Table<Tkey,Tval>_Hash) (const Tkey&);
- }
-
-
- template <class Tkey, class Tval>
- class CoolHash_Table<Tkey,Tval> : public CoolHash_Table {
- public:
- CoolHash_Table<Tkey,Tval> (); // Hash table of default size
- CoolHash_Table<Tkey,Tval> (unsigned long); // Hash table for at least size
- CoolHash_Table<Tkey,Tval> (const CoolHash_Table<Tkey,Tval>&); // Copy constructor
- ~CoolHash_Table<Tkey,Tval>(); // Destructor
-
- Boolean put (const Tkey&, const Tval&); // Hash key/value
- Boolean get (const Tkey&, Tval&); // Get associated value for key
- Boolean get_key (const Tval&, Tkey&); // Get associated key for value
- Boolean remove (const Tkey&); // Remove key/value from table
- void resize (long); // Resize for at least count
-
- Boolean find (const Tkey&); // Set current position
- const Tkey& key (); // Get key at current position
- Boolean remove (); // Remove key/value at curpos
- const Tval& value (); // value at current position
-
- CoolHash_Table<Tkey,Tval>& operator= (const CoolHash_Table<Tkey,Tval>&);
- Boolean operator== (const CoolHash_Table<Tkey,Tval>&); // is equal
- inline Boolean operator!= (const CoolHash_Table<Tkey,Tval>&); // is not eq
-
- inline void set_hash (CoolHash_Table<Tkey,Tval>_Hash); // Set hash function
- void set_key_compare (CoolHash_Table<Tkey,Tval>_Key_Compare = NULL);
- void set_value_compare (CoolHash_Table<Tkey,Tval>_Value_Compare = NULL);
-
- friend ostream& operator<< (ostream&, const CoolHash_Table<Tkey,Tval>&);
- inline friend ostream& operator<< (ostream&, const CoolHash_Table<Tkey,Tval>*);
-
- protected:
- CoolHash_Table<Tkey,Tval>_bucket* table; // Pointer to key/value buckets
- CoolHash_Table<Tkey,Tval>_Hash h_function; // Pointer to hash function
- static CoolHash_Table<Tkey,Tval>_Key_Compare compare_keys_s; // Key compare
- static CoolHash_Table<Tkey,Tval>_Value_Compare compare_values_s; // Value compare
- friend Boolean CoolHash_Table<Tkey,Tval>_keys_equal (const Tkey&, const Tkey&);
- friend Boolean CoolHash_Table<Tkey,Tval>_values_equal (const Tval&, const Tval&);
- friend unsigned long CoolHash_Table<Tkey,Tval>_default_hash (const Tkey& key);
- };
-
- // operator<< -- Overload the output operator to provide a crude print
- // capability for hash table objects
- // Input: ostream reference, hash table pointer
- // Output: None
-
- template <class Tkey, class Tval> CoolHash_Table {
- inline ostream& operator<< (ostream& os, const CoolHash_Table<Tkey,Tval>* h) {
- return operator<< (os, *h);
- }
- }
-
-
-
-
- // operator!= -- Determine if two hash tables are unequal
- // Input: this*, reference to second hash table
- // Output: TRUE/FALSE
-
- template <class Tkey, class Tval>
- inline Boolean CoolHash_Table<Tkey,Tval>::operator!= (const CoolHash_Table<Tkey,Tval>& t) {
- return (!operator== (t));
- }
-
-
-
-
- // Set_hash -- Set the hash function for this instance
- // Input: Pointer to hash function
- // Output: None
-
- template <class Tkey, class Tval>
- inline void CoolHash_Table<Tkey,Tval>::set_hash (CoolHash_Table<Tkey,Tval>_Hash h) {
- this->h_function = h;
- }
-
- #endif // End #ifdef of HASH_TABLEH
-